#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/fs/nvs.h>
#include <zephyr/logging/log.h>

#include "flash_ctrl.h"
#include "zephyr/logging/log_core.h"


LOG_MODULE_REGISTER(flash, LOG_LEVEL_DBG);


bool is_flash_init = false;
static struct nvs_fs fs;
static struct flash_pages_info fs_page_info;


int flash_device_init(void)
{

    int ret;

    fs.flash_device = NVS_PARTITION_DEVICE;
	if (!device_is_ready(fs.flash_device)) {
		LOG_ERR("Flash device %s is not ready", fs.flash_device->name);
		return 0;
	}
	else
	{
		LOG_INF("Flash device %s is ready", fs.flash_device->name);
	}

    fs.offset = NVS_PARTITION_OFFSET;
    ret = flash_get_page_info_by_offs(fs.flash_device, fs.offset, &fs_page_info);

    if (ret) {
        LOG_ERR("Unable to get page info");
        return 0;
    }

    fs.sector_size = fs_page_info.size;
	fs.sector_count = 3U;

    ret = nvs_mount(&fs);
	if (ret < 0) {
		LOG_ERR("Error mounting nvs: %d", ret);
		return 0;
	}
	else
	{
		LOG_INF("NVS mounted");
	}

    is_flash_init = true;

    return 1;
}


int flash_data_read(uint8_t id, uint8_t *data, uint32_t len)
{
    int ret;

    if (!is_flash_init) {
        LOG_ERR("Flash not initialized");
        return 0;
    }

    ret = nvs_read(&fs, id, data, len);
    if (ret < 0) {
        LOG_ERR("Error reading data from flash: %d", ret);
        return 0;
    }

    return 1;
}

int flash_data_write(uint8_t id, uint8_t *data, uint32_t len)
{
    int ret;

    if (!is_flash_init) {
        LOG_ERR("Flash not initialized");
        return 0;
    }

    ret = nvs_write(&fs, id, data, len);
    if (ret < 0) {
        LOG_ERR("Error writing data to flash: %d", ret);
        return 0;
    }

    return 1;
}